package com.soup.lab.basic.proxy;

import net.sf.cglib.proxy.*;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;

public class CGLibProxyTestCase {

    @Test
    public void test() {
        // CGLIB代理需要先构建Enhancer对象并进行一系列设置，然后根据设置创建代理对象
        Enhancer enhancer = new Enhancer();
        // 设置父类，这里可以是父类或者接口
        // 可以通过 enhancer.setInterfaces设置多个接口
        enhancer.setSuperclass(Duck.class);
        // 设置回调，对代理对象的调用，最后会委托给回调
        enhancer.setCallback(new DuckMethodInterceptor(new RubberDuck()));
        // 创建代理对象
        Duck apple = (Duck)enhancer.create();
        apple.bark();
    }

    interface Duck {
        void bark();
    }

    static class RubberDuck implements Duck {
        @Override
        public void bark() {
            System.out.println("bia~ bia~");
        }
    }

    static class DuckMethodInterceptor implements MethodInterceptor {

        private final Duck target;

        public DuckMethodInterceptor(Duck target) {
            this.target = target;
        }

        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            if("bark".equals(method.getName())) {
                System.out.println("Duck is barking...");
            }
            return method.invoke(target, args);
        }
    }


    @Test
    public void test2() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RubberDuck.class);
        enhancer.setCallback(new RubberDuckMethodInterceptor());
        Duck apple = (Duck)enhancer.create();
        apple.bark();
    }

    static class RubberDuckMethodInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            if("bark".equals(method.getName())) {
                System.out.println("Duck is barking...");
            }
            return proxy.invokeSuper(obj, args);
        }
    }

}
